import Foot from "./Foot";
import ScorePanel from "./ScorePanel";
import Snack from "./Snack";

// 游戏控制器，控制其他的所有类
class GameControl {
  // 定义三个属性
  // 蛇
  snack: Snack
  // 食物
  foot: Foot
  // 记分牌
  scorePanel: ScorePanel

  // 创建一个属性，来存储蛇的移动方向（也就是案件的方向）
  direction: string = ''

  // 创建一个属性 记录游戏是否结束
  isLive: boolean = true

  constructor() {
    this.snack = new Snack()
    this.foot = new Foot()
    this.scorePanel = new ScorePanel()

    this.init()
  }

  // 游戏初始化方法，调用后游戏开始
  init() {
    // 绑定键盘按下的事件
    document.addEventListener('keydown', this.keydownHandler.bind(this))

    // 调用run方法 使蛇移动
    this.run()
  }


  /**
   *  ArrowUp  Up(IE)
   *  ArrowDown  Down(IE)
   *  ArrowLeft  Left(IE)
   *  ArrowRight  Right(IE)
   */
  // 创建一个键盘按下的响应函数
  keydownHandler(event: KeyboardEvent) {
    // 需要检查event.key 的值是否合法，用户是否按了正确的按键
    if (event.key === 'ArrowUp' || event.key === 'Up' || event.key === 'ArrowDown'
      || event.key === 'Down' || event.key === 'ArrowLeft' || event.key === 'Left'
      || event.key === 'ArrowRight' || event.key === 'Right') {
      // 修改direction属性
      this.direction = event.key
    }
  }

  // 创建一个控制蛇移动的方向
  run() {
    /**
     * 根据方向（this.direction）来使蛇的位置改变
     * 向上 top 减少
     * 向下 top 增加
     * 向左 left 减少
     * 向右 left 增加
     */
    // 获取蛇现在的坐标
    let X = this.snack.X
    let Y = this.snack.Y

    // 根据按键方向来修改X值和Y值
    switch (this.direction) {
      case "ArrowUp":
      case "Up": //向上 top 减少
        Y -= 10
        break;
      case "ArrowDown":
      case "Down": //向下 top 增加
        Y += 10
        break
      case "ArrowLeft":
      case "Left": //向左 left 减少
        X -= 10
        break
      case "ArrowRight":
      case "Right": //向右 left 增加
        X += 10
        break
    }

    // 检查蛇是否迟到了食物
    this.checkEat(X, Y)

    // 修改蛇的X和Y
    try {
      this.snack.X = X
      this.snack.Y = Y
    } catch (e: any) {
      // 进入带catch 说明出现了异常，说明撞墙，游戏接触，弹出提示
      alert(e.message + 'GAME OVER!')
      // 将isLive改为false
      this.isLive = false
    }


    // 开启一个定时
    this.isLive && setTimeout(this.run.bind(this), 400 - (this.scorePanel.level - 1) * 30)
  }

  // 定义一个方法 用来检查蛇是否吃到食物
  checkEat(X: number, Y: number) {
    if (X === this.foot.X && Y === this.foot.Y) {
      // 食物的位置进行重置
      this.foot.change()
      // 分数增加
      this.scorePanel.addScore()
      // 蛇增加一节
      this.snack.addBody()
    }
  }

}

export default GameControl
